<!DOCTYPE HTML>
<html lang="zh-CN">


<head>
    <meta charset="utf-8">
    <meta name="keywords" content="Flutter&amp;Dart编码规范, jiodg45的博客">
    <meta name="description" content="">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <meta name="renderer" content="webkit|ie-stand|ie-comp">
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
    <!-- Global site tag (gtag.js) - Google Analytics -->


    <title>Flutter&amp;Dart编码规范 | jiodg45的博客</title>
    <link rel="icon" type="image/png" href="/jiodg45/favicon.png">

    <link rel="stylesheet" type="text/css" href="/jiodg45/libs/awesome/css/all.css">
    <link rel="stylesheet" type="text/css" href="/jiodg45/libs/materialize/materialize.min.css">
    <link rel="stylesheet" type="text/css" href="/jiodg45/libs/aos/aos.css">
    <link rel="stylesheet" type="text/css" href="/jiodg45/libs/animate/animate.min.css">
    <link rel="stylesheet" type="text/css" href="/jiodg45/libs/lightGallery/css/lightgallery.min.css">
    <link rel="stylesheet" type="text/css" href="/jiodg45/css/matery.css">
    <link rel="stylesheet" type="text/css" href="/jiodg45/css/my.css">

    <script src="/jiodg45/libs/jquery/jquery.min.js"></script>

<meta name="generator" content="Hexo 5.4.0">
<style>.github-emoji { position: relative; display: inline-block; width: 1.2em; min-height: 1.2em; overflow: hidden; vertical-align: top; color: transparent; }  .github-emoji > span { position: relative; z-index: 10; }  .github-emoji img, .github-emoji .fancybox { margin: 0 !important; padding: 0 !important; border: none !important; outline: none !important; text-decoration: none !important; user-select: none !important; cursor: auto !important; }  .github-emoji img { height: 1.2em !important; width: 1.2em !important; position: absolute !important; left: 50% !important; top: 50% !important; transform: translate(-50%, -50%) !important; user-select: none !important; cursor: auto !important; } .github-emoji-fallback { color: inherit; } .github-emoji-fallback img { opacity: 0 !important; }</style>
</head>




<body>
    <header class="navbar-fixed">
    <nav id="headNav" class="bg-color nav-transparent">
        <div id="navContainer" class="nav-wrapper container">
            <div class="brand-logo">
                <a href="/jiodg45/" class="waves-effect waves-light">
                    
                    <img src="/jiodg45/medias/logo.png" class="logo-img" alt="LOGO">
                    
                    <span class="logo-span">jiodg45的博客</span>
                </a>
            </div>
            

<a href="#" data-target="mobile-nav" class="sidenav-trigger button-collapse"><i class="fas fa-bars"></i></a>
<ul class="right nav-menu">
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/jiodg45/" class="waves-effect waves-light">
      
      <i class="fas fa-home" style="zoom: 0.6;"></i>
      
      <span>首页</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/jiodg45/tags" class="waves-effect waves-light">
      
      <i class="fas fa-tags" style="zoom: 0.6;"></i>
      
      <span>标签</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/jiodg45/categories" class="waves-effect waves-light">
      
      <i class="fas fa-bookmark" style="zoom: 0.6;"></i>
      
      <span>分类</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/jiodg45/archives" class="waves-effect waves-light">
      
      <i class="fas fa-archive" style="zoom: 0.6;"></i>
      
      <span>归档</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/jiodg45/about" class="waves-effect waves-light">
      
      <i class="fas fa-user-circle" style="zoom: 0.6;"></i>
      
      <span>关于</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/jiodg45/contact" class="waves-effect waves-light">
      
      <i class="fas fa-comments" style="zoom: 0.6;"></i>
      
      <span>留言板</span>
    </a>
    
  </li>
  
  <li class="hide-on-med-and-down nav-item">
    
    <a href="/jiodg45/friends" class="waves-effect waves-light">
      
      <i class="fas fa-address-book" style="zoom: 0.6;"></i>
      
      <span>友情链接</span>
    </a>
    
  </li>
  
  <li>
    <a href="#searchModal" class="modal-trigger waves-effect waves-light">
      <i id="searchIcon" class="fas fa-search" title="搜索" style="zoom: 0.85;"></i>
    </a>
  </li>
</ul>


<div id="mobile-nav" class="side-nav sidenav">

    <div class="mobile-head bg-color">
        
        <img src="/jiodg45/medias/logo.png" class="logo-img circle responsive-img">
        
        <div class="logo-name">jiodg45的博客</div>
        <div class="logo-desc">
            
            Never really desperate, only the lost of the soul.
            
        </div>
    </div>

    

    <ul class="menu-list mobile-menu-list">
        
        <li class="m-nav-item">
	  
		<a href="/jiodg45/" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-home"></i>
			
			首页
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/jiodg45/tags" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-tags"></i>
			
			标签
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/jiodg45/categories" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-bookmark"></i>
			
			分类
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/jiodg45/archives" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-archive"></i>
			
			归档
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/jiodg45/about" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-user-circle"></i>
			
			关于
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/jiodg45/contact" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-comments"></i>
			
			留言板
		</a>
          
        </li>
        
        <li class="m-nav-item">
	  
		<a href="/jiodg45/friends" class="waves-effect waves-light">
			
			    <i class="fa-fw fas fa-address-book"></i>
			
			友情链接
		</a>
          
        </li>
        
        
        <li><div class="divider"></div></li>
        <li>
            <a href="https://github.com/blinkfox/hexo-theme-matery" class="waves-effect waves-light" target="_blank">
                <i class="fab fa-github-square fa-fw"></i>Fork Me
            </a>
        </li>
        
    </ul>
</div>


        </div>

        
            <style>
    .nav-transparent .github-corner {
        display: none !important;
    }

    .github-corner {
        position: absolute;
        z-index: 10;
        top: 0;
        right: 0;
        border: 0;
        transform: scale(1.1);
    }

    .github-corner svg {
        color: #0f9d58;
        fill: #fff;
        height: 64px;
        width: 64px;
    }

    .github-corner:hover .octo-arm {
        animation: a 0.56s ease-in-out;
    }

    .github-corner .octo-arm {
        animation: none;
    }

    @keyframes a {
        0%,
        to {
            transform: rotate(0);
        }
        20%,
        60% {
            transform: rotate(-25deg);
        }
        40%,
        80% {
            transform: rotate(10deg);
        }
    }
</style>

<a href="https://github.com/blinkfox/hexo-theme-matery" class="github-corner tooltipped hide-on-med-and-down" target="_blank"
   data-tooltip="Fork Me" data-position="left" data-delay="50">
    <svg viewBox="0 0 250 250" aria-hidden="true">
        <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
        <path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
              fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
        <path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
              fill="currentColor" class="octo-body"></path>
    </svg>
</a>
        
    </nav>

</header>

    



<div class="bg-cover pd-header post-cover" style="background-image: url('/jiodg45/medias/featureimages/21.jpg')">
    <div class="container" style="right: 0px;left: 0px;">
        <div class="row">
            <div class="col s12 m12 l12">
                <div class="brand">
                    <h1 class="description center-align post-title">Flutter&amp;Dart编码规范</h1>
                </div>
            </div>
        </div>
    </div>
</div>




<main class="post-container content">

    
    <link rel="stylesheet" href="/jiodg45/libs/tocbot/tocbot.css">
<style>
    #articleContent h1::before,
    #articleContent h2::before,
    #articleContent h3::before,
    #articleContent h4::before,
    #articleContent h5::before,
    #articleContent h6::before {
        display: block;
        content: " ";
        height: 100px;
        margin-top: -100px;
        visibility: hidden;
    }

    #articleContent :focus {
        outline: none;
    }

    .toc-fixed {
        position: fixed;
        top: 64px;
    }

    .toc-widget {
        width: 345px;
        padding-left: 20px;
    }

    .toc-widget .toc-title {
        padding: 35px 0 15px 17px;
        font-size: 1.5rem;
        font-weight: bold;
        line-height: 1.5rem;
    }

    .toc-widget ol {
        padding: 0;
        list-style: none;
    }

    #toc-content {
        padding-bottom: 30px;
        overflow: auto;
    }

    #toc-content ol {
        padding-left: 10px;
    }

    #toc-content ol li {
        padding-left: 10px;
    }

    #toc-content .toc-link:hover {
        color: #42b983;
        font-weight: 700;
        text-decoration: underline;
    }

    #toc-content .toc-link::before {
        background-color: transparent;
        max-height: 25px;

        position: absolute;
        right: 23.5vw;
        display: block;
    }

    #toc-content .is-active-link {
        color: #42b983;
    }

    #floating-toc-btn {
        position: fixed;
        right: 15px;
        bottom: 76px;
        padding-top: 15px;
        margin-bottom: 0;
        z-index: 998;
    }

    #floating-toc-btn .btn-floating {
        width: 48px;
        height: 48px;
    }

    #floating-toc-btn .btn-floating i {
        line-height: 48px;
        font-size: 1.4rem;
    }
</style>
<div class="row">
    <div id="main-content" class="col s12 m12 l9">
        <!-- 文章内容详情 -->
<div id="artDetail">
    <div class="card">
        <div class="card-content article-info">
            <div class="row tag-cate">
                <div class="col s7">
                    
                    <div class="article-tag">
                        
                            <a href="/jiodg45/tags/flutter/">
                                <span class="chip bg-color">flutter</span>
                            </a>
                        
                    </div>
                    
                </div>
                <div class="col s5 right-align">
                    
                    <div class="post-cate">
                        <i class="fas fa-bookmark fa-fw icon-category"></i>
                        
                            <a href="/jiodg45/categories/flutter/" class="post-category">
                                flutter
                            </a>
                        
                    </div>
                    
                </div>
            </div>

            <div class="post-info">
                
                <div class="post-date info-break-policy">
                    <i class="far fa-calendar-minus fa-fw"></i>发布日期:&nbsp;&nbsp;
                    2021-03-11
                </div>
                

                

                

                

                
            </div>
        </div>
        <hr class="clearfix">

        

        

        <div class="card-content article-card-content">
            <div id="articleContent">
                <h2 id="Flutter-amp-Dart编码规范"><a href="#Flutter-amp-Dart编码规范" class="headerlink" title="Flutter&amp;Dart编码规范"></a>Flutter&amp;Dart编码规范</h2><h2 id="Dart"><a href="#Dart" class="headerlink" title="Dart"></a>Dart</h2><p>[effective-dart en]<a target="_blank" rel="noopener" href="https://dart.dev/guides/language/effective-dart">https://dart.dev/guides/language/effective-dart</a></p>
<p>[effective-dart zh]<a target="_blank" rel="noopener" href="https://www.dartcn.com/guides/language/effective-dart/">https://www.dartcn.com/guides/language/effective-dart/</a></p>
<h2 id="Flutter"><a href="#Flutter" class="headerlink" title="Flutter"></a>Flutter</h2><p><a target="_blank" rel="noopener" href="https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo">offical-style-guide en</a></p>
<h2 id="Lazy-programming"><a href="#Lazy-programming" class="headerlink" title="Lazy programming"></a>Lazy programming</h2><p>按需编写代码，不要添加未使用的代码,功能不准备上线的代码就先不要添加</p>
<p>比如临时给PO或者UI看的示例代码，可以新建poc或者spike分支,修改完后打本地包或者模拟器视频截图</p>
<p>不要写临时的解决方案的代码</p>
<h2 id="Write-Test-find-Bug"><a href="#Write-Test-find-Bug" class="headerlink" title="Write Test,find Bug"></a>Write Test,find Bug</h2><p>不仅仅是覆盖率100%,更要逻辑达到100%, 如三目运算,if/else不同的结果值验证</p>
<p>不要写这样的代码: write test laster</p>
<h2 id="Avoid-duplicating-state"><a href="#Avoid-duplicating-state" class="headerlink" title="Avoid duplicating state"></a>Avoid duplicating state</h2><p>不要复制活动状态</p>
<h2 id="Getters-feel-faster-than-methods"><a href="#Getters-feel-faster-than-methods" class="headerlink" title="Getters feel faster than methods"></a>Getters feel faster than methods</h2><p>简单的数据操作使用get，如获取缓存状态O(1)</p>
<p>复杂耗时的操作使用方法</p>
<h2 id="No-synchronous-slow-work"><a href="#No-synchronous-slow-work" class="headerlink" title="No synchronous slow work"></a>No synchronous slow work</h2><p>不要同步执行耗时的操作,比如磁盘或网络存读取大文件,音视频的压缩</p>
<h2 id="Layers"><a href="#Layers" class="headerlink" title="Layers"></a>Layers</h2><p>Flutter框架很多类都遵循了单一职责的原则,尽可能使用更简洁的Widget</p>
<h2 id="Avoid-interleaving-multiple-concepts-together"><a href="#Avoid-interleaving-multiple-concepts-together" class="headerlink" title="Avoid interleaving multiple concepts together"></a>Avoid interleaving multiple concepts together</h2><p>避免将多个概念交织在一起,如一个申明为child的widget,那么就不应该在内部再去判断child的类型</p>
<p>每个一个RenderObjects处理一个单一的类容,如处理Cliping和Opacity,而不是在一个RenderObject中同时处理这两个行为</p>
<p>尽量使用不可变的元素代替可变的元素</p>
<h2 id="Avoid-secret-or-global-state"><a href="#Avoid-secret-or-global-state" class="headerlink" title="Avoid secret (or global) state"></a>Avoid secret (or global) state</h2><p>避免使用全局的变量和状态,最好通过类来管理</p>
<h2 id="Prefer-general-APIs-but-use-dedicated-APIs-where-there-is-a-reason"><a href="#Prefer-general-APIs-but-use-dedicated-APIs-where-there-is-a-reason" class="headerlink" title="Prefer general APIs, but use dedicated APIs where there is a reason"></a>Prefer general APIs, but use dedicated APIs where there is a reason</h2><p>推荐使用全局的API,但如果是一些特殊用途,推荐使用专门的API,例如一些性能问题,如切除圆角,可以使用一个特定的API来完成</p>
<h2 id="Avoid-the-lowest-common-denominator"><a href="#Avoid-the-lowest-common-denominator" class="headerlink" title="Avoid the lowest common denominator"></a>Avoid the lowest common denominator</h2><p>避免使用最小分母, 比如platform方法,只有某个单独的平台可以使用,不建议使用</p>
<h2 id="Avoid-APIs-that-encourage-bad-practices"><a href="#Avoid-APIs-that-encourage-bad-practices" class="headerlink" title="Avoid APIs that encourage bad practices"></a>Avoid APIs that encourage bad practices</h2><p>字符串操作,解析的代码不是很安全,导致容易被攻击,如js执行脚本<br>性能差,耗时操作的任务通过Future和Stream返回</p>
<h2 id="Avoid-exposing-API-cliffs"><a href="#Avoid-exposing-API-cliffs" class="headerlink" title="Avoid exposing API cliffs"></a>Avoid exposing API cliffs</h2><p>使用定义清晰的API,如插件层的代码调用,注明Android和iOS调用的方法，以及API文档链接，方便查阅</p>
<h2 id="Avoid-exposing-API-oceans"><a href="#Avoid-exposing-API-oceans" class="headerlink" title="Avoid exposing API oceans"></a>Avoid exposing API oceans</h2><p>避免底层的API被直接调用,更小的API更容易理解， 可以使用hide关键字进行约束</p>
<h2 id="Solve-real-problems-by-literally-solving-a-real-problem"><a href="#Solve-real-problems-by-literally-solving-a-real-problem" class="headerlink" title="Solve real problems by literally solving a real problem"></a>Solve real problems by literally solving a real problem</h2><p>通过聆听一个真是用户的想法来来做好一个功能</p>
<h2 id="Get-early-feedback-when-designing-new-APIs"><a href="#Get-early-feedback-when-designing-new-APIs" class="headerlink" title="Get early feedback when designing new APIs"></a>Get early feedback when designing new APIs</h2><p>尽早的对给出的API反馈</p>
<h2 id="Only-log-actionable-messages-to-the-console"><a href="#Only-log-actionable-messages-to-the-console" class="headerlink" title="Only log actionable messages to the console"></a>Only log actionable messages to the console</h2><p>仅将可操作的消息记录在控制台,设置不同的flags, logLevel, feature name, class Name, function,line ,time</p>
<p>不要随意的打印用户的隐私信息</p>
<h2 id="Plugin-compatibility"><a href="#Plugin-compatibility" class="headerlink" title="Plugin compatibility"></a>Plugin compatibility</h2><p>版本约定, 1.0.0<br>设定Tag<br>详细的README介绍<br>Example<br>不要使用过期的API<br>尽可能的兼容低版本<br>统一的API接口,定义清晰的PlatformInteface<br>Native平台的方法备注<br>指定CoderOwner</p>
<h2 id="Workarounds"><a href="#Workarounds" class="headerlink" title="Workarounds"></a>Workarounds</h2><h2 id="Avoid-abandonware"><a href="#Avoid-abandonware" class="headerlink" title="Avoid abandonware"></a>Avoid abandonware</h2><p>避免废弃的软件,没有维护和热度不高的开源软件不要随便使用<br>不要注释代码</p>
<h2 id="Widget-libraries-follow-the-latest-OEM-behavior"><a href="#Widget-libraries-follow-the-latest-OEM-behavior" class="headerlink" title="Widget libraries follow the latest OEM behavior"></a>Widget libraries follow the latest OEM behavior</h2><p>针对于小部件Widget可采用新增的方式,而不是从新修改</p>
<p>Factory适配,微小的细节改动,如text增加maxline</p>
<p>新建widget,如broken级别的改动,如SearchBar,布局，边框,按钮行为，图标,交互效果全部改变,则需要新建一个</p>
<h2 id="Documentation-dartdocs-javadocs-etc"><a href="#Documentation-dartdocs-javadocs-etc" class="headerlink" title="Documentation (dartdocs, javadocs, etc)"></a>Documentation (dartdocs, javadocs, etc)</h2><p>使用<code>dartdoc</code>来生成Dart Documentation， <a target="_blank" rel="noopener" href="https://dart.dev/guides/language/effective-dart/documentation#doc-comments">https://dart.dev/guides/language/effective-dart/documentation#doc-comments</a></p>
<h2 id="Answer-your-own-questions-straight-away"><a href="#Answer-your-own-questions-straight-away" class="headerlink" title="Answer your own questions straight away"></a>Answer your own questions straight away</h2><p>避免口头交接,将发生的问题归类会中,以便于后面的人能够直接上手</p>
<h2 id="Avoid-useless-documentation"><a href="#Avoid-useless-documentation" class="headerlink" title="Avoid useless documentation"></a>Avoid useless documentation</h2><p>避免使用无效的文档注释, 如简单粗暴的对属性变量重复解释</p>
<p>// BAD:</p>
<p>/// The background color.<br>final Color backgroundColor;</p>
<p>// GOOD:</p>
<p>/// The color with which to fill the circle. Changing the background<br>/// color will cause the avatar to animate to the new color.<br>final Color backgroundColor;</p>
<h2 id="Writing-prompts-for-good-documentation"><a href="#Writing-prompts-for-good-documentation" class="headerlink" title="Writing prompts for good documentation"></a>Writing prompts for good documentation</h2><figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD:</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/// <span class="markdown">Note: It is important to be aware of the fact that in the</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">absence of an explicit value, this property defaults to 2.</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/// <span class="markdown">Defaults to 2.</span></span></span><br></pre></td></tr></tbody></table></figure>

<h2 id="Leave-breadcrumbs-in-the-comments"><a href="#Leave-breadcrumbs-in-the-comments" class="headerlink" title="Leave breadcrumbs in the comments"></a>Leave breadcrumbs in the comments</h2><figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/// <span class="markdown">An object representing a sequence of recorded graphical operations.</span></span></span><br><span class="line"><span class="comment">///</span></span><br><span class="line"><span class="comment">/// <span class="markdown">To create a [Picture], use a [PictureRecorder].</span></span></span><br><span class="line"><span class="comment">///</span></span><br><span class="line"><span class="comment">/// <span class="markdown">A [Picture] can be placed in a [Scene] using a [SceneBuilder], via</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">the [SceneBuilder.addPicture] method. A [Picture] can also be</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">drawn into a [Canvas], using the [Canvas.drawPicture] method.</span></span></span><br><span class="line"><span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Picture</span> ...</span></span><br></pre></td></tr></tbody></table></figure>

<h2 id="Refactor-the-code-when-the-documentation-would-be-incomprehensible"><a href="#Refactor-the-code-when-the-documentation-would-be-incomprehensible" class="headerlink" title="Refactor the code when the documentation would be incomprehensible"></a>Refactor the code when the documentation would be incomprehensible</h2><p>如果代码逻辑本省比较难以叙述,让文档变得复杂,可以考虑修改代码结构,帮助理解, 如通知的deeplink的文档描述</p>
<h2 id="Canonical-terminology"><a href="#Canonical-terminology" class="headerlink" title="Canonical terminology"></a>Canonical terminology</h2><p>method    一个类的方法描述<br>function  一个不在类中定义的函数<br>parameter 传递给闭包的参数<br>argument  函数中使用的参数<br>使用<code>call</code>进行方法回调</p>
<h2 id="Use-correct-grammar"><a href="#Use-correct-grammar" class="headerlink" title="Use correct grammar"></a>Use correct grammar</h2><p>类型指定,通过<code>[]</code>表示一个存在的Object,通过<code>method</code>,<code>function</code>,<code>parameter</code>等同通用的修饰词语来说明它</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/// <span class="markdown">[foo] must not be null.</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/// <span class="markdown">The [foo] argument must not be null.</span></span></span><br></pre></td></tr></tbody></table></figure>

<h2 id="Use-the-passive-voice-recommend-do-not-require"><a href="#Use-the-passive-voice-recommend-do-not-require" class="headerlink" title="Use the passive voice; recommend, do not require"></a>Use the passive voice; recommend, do not require</h2><p>不要使用<code>you</code>或者<code>we</code>等命令的语气,避免过度主观的判定</p>
<h2 id="Provide-sample-code"><a href="#Provide-sample-code" class="headerlink" title="Provide sample code"></a>Provide sample code</h2><p>提供示例代码,使用<code>{@tool snippet}...{@end-tool}</code>修饰,这将会让dart-doc来自动生成文档</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/// <span class="markdown">A scrollable list of widgets arranged linearly.</span></span></span><br><span class="line"><span class="comment">/// </span></span><br><span class="line"><span class="comment">/// <span class="markdown">...</span></span></span><br><span class="line"><span class="comment">/// </span></span><br><span class="line"><span class="comment">/// <span class="markdown">{@tool snippet}</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">An infinite list of children:</span></span></span><br><span class="line"><span class="comment">///</span></span><br><span class="line"><span class="comment">/// <span class="markdown"><span class="code">```dart</span></span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">ListView.builder(</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">  padding: EdgeInsets.all(8.0),</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">  itemExtent: 20.0,</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">  itemBuilder: (BuildContext context, int index) {</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown"><span class="code">    return Text('entry $index');</span></span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">  },</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">)</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown"><span class="code">```</span></span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">{@end-tool}</span></span></span><br></pre></td></tr></tbody></table></figure>

<h2 id="Provide-full-application-samples"><a href="#Provide-full-application-samples" class="headerlink" title="Provide full application samples."></a>Provide full application samples.</h2><p>使用全文档示例子</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">{<span class="meta">@tool</span> dartpad --template=&lt;template&gt;} …​ {<span class="meta">@end</span>-tool}</span><br><span class="line">{<span class="meta">@tool</span> sample --template=&lt;template&gt;} …​ {<span class="meta">@end</span>-tool}</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Provide-illustractions-diagrams-or-screenshots"><a href="#Provide-illustractions-diagrams-or-screenshots" class="headerlink" title="Provide illustractions, diagrams or screenshots"></a>Provide illustractions, diagrams or screenshots</h2><h2 id="Use-for-public-quality-private-documentation"><a href="#Use-for-public-quality-private-documentation" class="headerlink" title="Use /// for public-quality private documentation"></a>Use /// for public-quality private documentation</h2><h2 id="Dartdoc-templates-and-macro"><a href="#Dartdoc-templates-and-macro" class="headerlink" title="Dartdoc templates and macro"></a>Dartdoc templates and macro</h2><figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/// <span class="markdown">{@template <span class="xml"><span class="tag">&lt;<span class="name">id</span>&gt;</span></span>}</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">...</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">{@endtemplate}</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"><span class="comment">/// <span class="markdown">{@template flutter.rendering.Layer.findAnnotations.aboutAnnotations}</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">Annotations are great!</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">{@endtemplate</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">// BAD:</span></span><br><span class="line"><span class="comment">/// <span class="markdown">{@template the<span class="emphasis">_stuff!}</span></span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">This is some great stuff!</span></span></span><br><span class="line"><span class="comment">/// <span class="markdown">{@endtemplate}</span></span></span><br></pre></td></tr></tbody></table></figure>

<h2 id="Dartdoc-specific-requirements"><a href="#Dartdoc-specific-requirements" class="headerlink" title="Dartdoc-specific requirements"></a>Dartdoc-specific requirements</h2><p>Object使用<code>[]</code>描述,其它简单类型的数据使用``来描述</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// GOOD</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">/// <span class="markdown">Creates a foobar, which allows a baz to quux the bar.</span></span></span><br><span class="line">  <span class="comment">///</span></span><br><span class="line">  <span class="comment">/// <span class="markdown">The [bar] argument must not be null.</span></span></span><br><span class="line">  <span class="comment">///</span></span><br><span class="line">  <span class="comment">/// <span class="markdown">The <span class="code">`baz`</span> argument must be greater than zero.</span></span></span><br><span class="line">  Foo({ <span class="keyword">this</span>.bar, <span class="built_in">int</span> baz }) : <span class="keyword">assert</span>(bar != <span class="keyword">null</span>), <span class="keyword">assert</span>(baz &gt; <span class="number">0</span>);</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Coding-patterns-and-catching-bugs-early"><a href="#Coding-patterns-and-catching-bugs-early" class="headerlink" title="Coding patterns and catching bugs early"></a>Coding patterns and catching bugs early</h2><p>使用assert断言进行描述,尤其是工具类,构造函数</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">RenderBox</span> <span class="keyword">extends</span> <span class="title">RenderObject</span> </span>{</span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line"></span><br><span class="line">  <span class="built_in">double</span> getDistanceToBaseline(TextBaseline baseline, {<span class="built_in">bool</span> onlyReal: <span class="keyword">false</span>}) {</span><br><span class="line">    <span class="comment">// simple asserts:</span></span><br><span class="line">    <span class="keyword">assert</span>(!needsLayout);</span><br><span class="line">    <span class="keyword">assert</span>(!_debugDoingBaseline);</span><br><span class="line">    <span class="comment">// more complicated asserts:</span></span><br><span class="line">    <span class="keyword">assert</span>(() {</span><br><span class="line">      <span class="keyword">final</span> RenderObject parent = <span class="keyword">this</span>.parent;</span><br><span class="line">      <span class="keyword">if</span> (owner.debugDoingLayout)</span><br><span class="line">        <span class="keyword">return</span> (RenderObject.debugActiveLayout == parent) &amp;&amp;</span><br><span class="line">            parent.debugDoingThisLayout;</span><br><span class="line">      <span class="keyword">if</span> (owner.debugDoingPaint)</span><br><span class="line">        <span class="keyword">return</span> ((RenderObject.debugActivePaint == parent) &amp;&amp;</span><br><span class="line">                parent.debugDoingThisPaint) ||</span><br><span class="line">            ((RenderObject.debugActivePaint == <span class="keyword">this</span>) &amp;&amp; debugDoingThisPaint);</span><br><span class="line">      <span class="keyword">assert</span>(parent == <span class="keyword">this</span>.parent);</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    });</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">    <span class="keyword">return</span> <span class="number">0.0</span>;</span><br><span class="line">  }</span><br><span class="line"></span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<p>使用合适的错误类型,来处理异常</p>
<p>如项目中比较常见的<code>BlocProvider.of</code></p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">throw</span> FlutterError(</span><br><span class="line">        <span class="string">'''</span></span><br><span class="line"><span class="string">        BlocProvider.of() called with a context that does not contain a Bloc/Cubit of type <span class="subst">$T</span>.</span></span><br><span class="line"><span class="string">        No ancestor could be found starting from the context that was passed to BlocProvider.of&lt;<span class="subst">$T</span>&gt;().</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">        This can happen if the context you used comes from a widget above the BlocProvider.</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">        The context used was: <span class="subst">$context</span></span></span><br><span class="line"><span class="string">        '''</span>,</span><br><span class="line">      );</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Prefer-specialized-functions-methods-and-constructors"><a href="#Prefer-specialized-functions-methods-and-constructors" class="headerlink" title="Prefer specialized functions, methods and constructors"></a>Prefer specialized functions, methods and constructors</h2><p>优先选择合适的便利的构造函数和方法</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD:</span></span><br><span class="line"><span class="keyword">const</span> EdgeInsets.TRBL(<span class="number">0.0</span>, <span class="number">8.0</span>, <span class="number">0.0</span>, <span class="number">8.0</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"><span class="keyword">const</span> EdgeInsets.symmetric(horizontal: <span class="number">8.0</span>);</span><br><span class="line"></span><br></pre></td></tr></tbody></table></figure>

<h2 id="Minimize-the-visibility-scope-of-constants"><a href="#Minimize-the-visibility-scope-of-constants" class="headerlink" title="Minimize the visibility scope of constants"></a>Minimize the visibility scope of constants</h2><p>尽可能的缩小变量的作用域范围,优先使用本地变量而不是全局变量</p>
<p>推荐的优先级范围如下: </p>
<p>本地变量 -&gt; 类变量 -&gt; 类所在文件变量 -&gt; 全局变量</p>
<h2 id="Avoid-using-if-chains-or-or-with-enum-values"><a href="#Avoid-using-if-chains-or-or-with-enum-values" class="headerlink" title="Avoid using if chains or ?: or == with enum values"></a>Avoid using if chains or ?: or == with enum values</h2><p>避免enum的选择判断,尽量使用switch进行描述， </p>
<h2 id="Avoid-using-var-and-dynamic"><a href="#Avoid-using-var-and-dynamic" class="headerlink" title="Avoid using var and dynamic"></a>Avoid using var and dynamic</h2><p>尽量避免使用<code>var</code>和<code>dynamic</code>,var会导致变量存在被修改的潜在可能性，<code>dynamic</code>容易导致类型匹配错误.</p>
<h2 id="Avoid-using-library-and-part-of"><a href="#Avoid-using-library-and-part-of" class="headerlink" title="Avoid using library and part of."></a>Avoid using library and part of.</h2><p>每个类的共有私有关系需要有明确的定义,在对外提供的接口文件中需要有清晰的定义</p>
<h2 id="Avoid-using-extension"><a href="#Avoid-using-extension" class="headerlink" title="Avoid using extension."></a>Avoid using extension.</h2><p><code>extension</code>不利于整理文档,对于类来说,推荐创建新的类或者方法来扩充类容</p>
<p>对于枚举值,个人还是觉得使用<code>extension</code>比较容易解读一些</p>
<h2 id="Avoid-using-FutureOr"><a href="#Avoid-using-FutureOr" class="headerlink" title="Avoid using FutureOr"></a>Avoid using FutureOr<t></t></h2><p>它会导致API的安全性较差,难以准确判断类型,用于解释dart内部的future描述</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">///<span class="markdown">BAD ❌</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">extension</span> BridgeMethodExtension <span class="keyword">on</span> BridgeMethod {</span><br><span class="line">  <span class="comment">/// <span class="markdown">Calls the [BridgeMethodDelegate] with optinal [args].</span></span></span><br><span class="line">  <span class="comment">///</span></span><br><span class="line">  <span class="comment">/// <span class="markdown">[args] are processed using [arguments] so see there for details.</span></span></span><br><span class="line">  FutureOr&lt;<span class="built_in">Object</span>&gt; call([<span class="built_in">List</span>&lt;<span class="built_in">Object</span>&gt; args]) {</span><br><span class="line">    <span class="keyword">return</span> delegate(_arguments(args));</span><br><span class="line">  }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">extension</span> BridgeMethodGroupExtension <span class="keyword">on</span> BridgeMethodGroup {</span><br><span class="line">  BridgeMethodDelegate <span class="keyword">operator</span> [](<span class="built_in">String</span> methodName) {</span><br><span class="line">    <span class="keyword">final</span> foundMethods = bridgeMethods().where(</span><br><span class="line">      (method) =&gt; method.name == methodName,</span><br><span class="line">    );</span><br><span class="line">    <span class="keyword">assert</span>(</span><br><span class="line">      foundMethods.isNotEmpty,</span><br><span class="line">      <span class="string">'no bridge method found for name [<span class="subst">$methodName</span>]'</span>,</span><br><span class="line">    );</span><br><span class="line">    <span class="keyword">assert</span>(</span><br><span class="line">      foundMethods.length == <span class="number">1</span>,</span><br><span class="line">      <span class="string">'multiple bridge methods found for name [<span class="subst">$methodName</span>]'</span>,</span><br><span class="line">    );</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> foundMethods.single.delegate;</span><br><span class="line">  }</span><br><span class="line"></span><br><span class="line">  <span class="comment">/// <span class="markdown">Calls the [BridgeMethodDelegate] with a specific [methodName] with optional [args].</span></span></span><br><span class="line">  <span class="comment">///</span></span><br><span class="line">  <span class="comment">/// <span class="markdown">[args] are processed using [arguments] so see there for details.</span></span></span><br><span class="line">  FutureOr&lt;<span class="built_in">Object</span>&gt; call(<span class="built_in">String</span> methodName, [<span class="built_in">List</span>&lt;<span class="built_in">Object</span>&gt; args]) {</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>[methodName](_arguments(args));</span><br><span class="line">  }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Never-check-if-a-port-is-available-before-using-it-never-add-timeouts-and-other-race-conditions"><a href="#Never-check-if-a-port-is-available-before-using-it-never-add-timeouts-and-other-race-conditions" class="headerlink" title="Never check if a port is available before using it, never add timeouts, and other race conditions."></a>Never check if a port is available before using it, never add timeouts, and other race conditions.</h2><p>在使用一个端口之前不要去检查它,不要促发超时和其它条件竞争</p>
<h2 id="Avoid-mysterious-and-magical-numbers-that-lack-a-clear-derivation"><a href="#Avoid-mysterious-and-magical-numbers-that-lack-a-clear-derivation" class="headerlink" title="Avoid mysterious and magical numbers that lack a clear derivation"></a>Avoid mysterious and magical numbers that lack a clear derivation</h2><p>避免使用缺乏推导的数字,计算过程也写在代码中</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD</span></span><br><span class="line">expect(rect.left, <span class="number">4.24264068712</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD</span></span><br><span class="line">expect(rect.left, <span class="number">3.0</span> * math.sqrt(<span class="number">2</span>));</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Have-good-hygiene-when-using-temporary-directories"><a href="#Have-good-hygiene-when-using-temporary-directories" class="headerlink" title="Have good hygiene when using temporary directories"></a>Have good hygiene when using temporary directories</h2><p>使用临时目录时要注意资源的清除与释放,尤其是在测试ut中, 如果不清除临时文件可能导致其它测试ut失败</p>
<p>使用<code>createTempSync</code>和<code>tryToDelete</code>,来处理测试临时文件</p>
<h2 id="Perform-dirty-checks-in-setters"><a href="#Perform-dirty-checks-in-setters" class="headerlink" title="Perform dirty checks in setters"></a>Perform dirty checks in setters</h2><p>对触发其它逻辑执行和状态改变的操作检查<code>setters</code>属性是否真的需要改变</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/// <span class="markdown">Documentation here (don't wait for a later commit).</span></span></span><br><span class="line">TheType <span class="keyword">get</span> theProperty =&gt; _theProperty;</span><br><span class="line">TheType _theProperty;</span><br><span class="line"><span class="keyword">void</span> <span class="keyword">set</span> theProperty(TheType value) {</span><br><span class="line">  <span class="keyword">assert</span>(value != <span class="keyword">null</span>);</span><br><span class="line">  <span class="keyword">if</span> (_theProperty == value)</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  _theProperty = value;</span><br><span class="line">  markNeedsWhatever(); <span class="comment">// the method to mark the object dirty</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Common-boilerplates-for-operator-and-hashCode"><a href="#Common-boilerplates-for-operator-and-hashCode" class="headerlink" title="Common boilerplates for operator == and hashCode"></a>Common boilerplates for operator == and hashCode</h2><p>使用通用的 <code>==</code>来判断属性</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@override</span></span><br><span class="line"><span class="built_in">bool</span> <span class="keyword">operator</span> ==(<span class="built_in">Object</span> other) {</span><br><span class="line">  <span class="keyword">if</span> (other.runtimeType != runtimeType)</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">  <span class="keyword">return</span> other <span class="keyword">is</span> Foo </span><br><span class="line">      &amp;&amp; other.bar == bar</span><br><span class="line">      &amp;&amp; other.baz == baz</span><br><span class="line">      &amp;&amp; other.quux == quux;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@override</span></span><br><span class="line"><span class="built_in">int</span> <span class="keyword">get</span> hashCode =&gt; hashValues(bar, baz, quux);</span><br></pre></td></tr></tbody></table></figure>


<h2 id="Override-toString"><a href="#Override-toString" class="headerlink" title="Override toString"></a>Override toString</h2><p>重写<code>toString</code>用于诊断</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">@override</span></span><br><span class="line"><span class="built_in">String</span> toString() =&gt; <span class="string">'<span class="subst">${objectRuntimeType(<span class="keyword">this</span>, <span class="string">'NameOfObject'</span>)}</span>(<span class="subst">$bar</span>, <span class="subst">$baz</span>, <span class="subst">$quux</span>)'</span>;</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Be-explicit-about-dispose-and-the-object-lifecycle"><a href="#Be-explicit-about-dispose-and-the-object-lifecycle" class="headerlink" title="Be explicit about dispose() and the object lifecycle"></a>Be explicit about dispose() and the object lifecycle</h2><p>在dispose的时候释放和类相关的资源.如timer,streamSubscription</p>
<h2 id="Test-APIs-belong-in-the-test-frameworks"><a href="#Test-APIs-belong-in-the-test-frameworks" class="headerlink" title="Test APIs belong in the test frameworks"></a>Test APIs belong in the test frameworks</h2><p>测试库只在测试单元中使用，不能集成到正式环境中，避免被滥用</p>
<h2 id="Immutable-classes-should-not-have-hidden-state"><a href="#Immutable-classes-should-not-have-hidden-state" class="headerlink" title="Immutable classes should not have hidden state"></a>Immutable classes should not have hidden state</h2><p>不可变的类,不要申明私有属性</p>
<h2 id="Begin-global-constant-names-with-prefix-“k”"><a href="#Begin-global-constant-names-with-prefix-“k”" class="headerlink" title="Begin global constant names with prefix “k”"></a>Begin global constant names with prefix “k”</h2><p>全局常量使用<code>k</code>开头</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="built_in">double</span> kParagraphSpacing = <span class="number">1.5</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="built_in">String</span> kSaveButtonTitle = <span class="string">'Save'</span>;</span><br><span class="line"><span class="keyword">const</span> Color _kBarrierColor = Colors.black54;</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Avoid-abbreviations"><a href="#Avoid-abbreviations" class="headerlink" title="Avoid abbreviations"></a>Avoid abbreviations</h2><p>避免单词缩写</p>
<h2 id="Avoid-anonymous-parameter-names"><a href="#Avoid-anonymous-parameter-names" class="headerlink" title="Avoid anonymous parameter names"></a>Avoid anonymous parameter names</h2><p>避免匿名的参数</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// GOOD</span></span><br><span class="line">onTapDown: (TapDownDetails details) { <span class="built_in">print</span>(<span class="string">'hello!'</span>); }, </span><br><span class="line"></span><br><span class="line"><span class="comment">// BAD</span></span><br><span class="line">onTapUp: (_) { <span class="built_in">print</span>(<span class="string">'good bye'</span>); },</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Naming-rules-for-typedefs-and-function-variables"><a href="#Naming-rules-for-typedefs-and-function-variables" class="headerlink" title="Naming rules for typedefs and function variables"></a>Naming rules for typedefs and function variables</h2><p>为函数定义别名,避免直接在方法中使用</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> ArgumentCallback&lt;T&gt; = <span class="keyword">void</span> <span class="built_in">Function</span>(T argument);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">///<span class="markdown">BAD</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Exmaple</span> </span>{</span><br><span class="line">   Exmaple(<span class="built_in">Function</span>(T argument) callback);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">///<span class="markdown">BAD</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Exmaple</span> </span>{</span><br><span class="line">   Exmaple(ArgumentCallback&lt;T&gt; callback);</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Spell-words-in-identifiers-and-comments-correctly"><a href="#Spell-words-in-identifiers-and-comments-correctly" class="headerlink" title="Spell words in identifiers and comments correctly"></a>Spell words in identifiers and comments correctly</h2><p>采用正确的拼接单词,不要采用谐音,保证单词的准确性,不确定的单词多百度</p>
<p>例如 ‘colors’, 而不是 ‘colorz’.</p>
<h2 id="Capitalize-identifiers-consistent-with-their-spelling"><a href="#Capitalize-identifiers-consistent-with-their-spelling" class="headerlink" title="Capitalize identifiers consistent with their spelling"></a>Capitalize identifiers consistent with their spelling</h2><p>例如使用<code>toobar</code>,<code>scrollbar</code>,因为它们的组合是一个完整的单词,<br>而<code>appBar</code>和<code>tabBar</code>在官方文档中有定义,所以<code>Bar</code>使用大写</p>
<h2 id="Avoid-double-negatives-in-APIs"><a href="#Avoid-double-negatives-in-APIs" class="headerlink" title="Avoid double negatives in APIs"></a>Avoid double negatives in APIs</h2><p>避免API中使用双重否定语句,如<code>input.disabled = false or widget.hidden = false</code></p>
<h2 id="Prefer-naming-the-argument-to-a-setter-value"><a href="#Prefer-naming-the-argument-to-a-setter-value" class="headerlink" title="Prefer naming the argument to a setter value"></a>Prefer naming the argument to a setter value</h2><p>?? 没看明白</p>
<h2 id="Qualify-variables-and-methods-used-only-for-debugging"><a href="#Qualify-variables-and-methods-used-only-for-debugging" class="headerlink" title="Qualify variables and methods used only for debugging"></a>Qualify variables and methods used only for debugging</h2><p>调试相关的变量定义，设置固定的前缀<code>_debug</code><br>异常bug查找追踪 </p>
<p><code>[JIR-TICKET] {className} {methodName} {NO.} {cutsom string}</code></p>
<h2 id="Avoid-naming-undocumented-libraries"><a href="#Avoid-naming-undocumented-libraries" class="headerlink" title="Avoid naming undocumented libraries"></a>Avoid naming undocumented libraries</h2><p>不要使用库的关键字</p>
<h2 id="Avoid-checking-in-comments-that-ask-questions"><a href="#Avoid-checking-in-comments-that-ask-questions" class="headerlink" title="Avoid checking in comments that ask questions"></a>Avoid checking in comments that ask questions</h2><p>不要采用问答的形式来吸引读者的注意</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD:</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// What should this be?</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// This is a workaround.</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// According to this specification, this should be 2.0, but according to that</span></span><br><span class="line"><span class="comment">// specification, it should be 3.0. We split the difference and went with</span></span><br><span class="line"><span class="comment">// 2.5, because we didn't know what else to do.</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// TODO(username): Converting color to RGB because class Color doesn't support</span></span><br><span class="line"><span class="comment">//                 hex yet. See http://link/to/a/bug/123</span></span><br></pre></td></tr></tbody></table></figure>

<h2 id="Comment-all-ignores"><a href="#Comment-all-ignores" class="headerlink" title="Comment all // ignores"></a>Comment all // ignores</h2><p>如非必要,尽量不要写编译警告的代码，并备注原因</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">foo(); <span class="comment">// ignore: lint_code, https://link.to.bug/goes/here</span></span><br><span class="line"></span><br><span class="line">foo(); <span class="comment">// ignore: lint_code, sadly there is no choice but to do</span></span><br><span class="line"><span class="comment">// this because we need to twiddle the quux and the bar is zorgle.</span></span><br></pre></td></tr></tbody></table></figure>

<h2 id="Comment-all-test-skips"><a href="#Comment-all-test-skips" class="headerlink" title="Comment all test skips"></a>Comment all test skips</h2><p>在极少数的情况下,可能需要跳过某一些测试方法,使用skip指定,并备注原因</p>
<h2 id="Comment-empty-closures-to-setState"><a href="#Comment-empty-closures-to-setState" class="headerlink" title="Comment empty closures to setState"></a>Comment empty closures to setState</h2><p>在setState中对空的实现添加一些文档注释</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">setState(() app{ <span class="comment">/* The animation ticked. We use the animation's value in the build method. */</span> });</span><br></pre></td></tr></tbody></table></figure>


<h2 id="Formatting"><a href="#Formatting" class="headerlink" title="Formatting"></a>Formatting</h2><p>提交代码时,执行格式化<code>dartfmt .</code>,减少手工格式化</p>
<h2 id="Constructors-come-first-in-a-class"><a href="#Constructors-come-first-in-a-class" class="headerlink" title="Constructors come first in a class"></a>Constructors come first in a class</h2><p>构造函数放在类的开始,帮助读者更快速的理解这个类的结构</p>
<h2 id="Order-other-class-members-in-a-way-that-makes-sense"><a href="#Order-other-class-members-in-a-way-that-makes-sense" class="headerlink" title="Order other class members in a way that makes sense"></a>Order other class members in a way that makes sense</h2><p>类的方法,静态变量等属性的排序.</p>
<p>Constructors, with the default constructor first.</p>
<p>Constants of the same type as the class.</p>
<p>Static methods that return the same type as the class.</p>
<p>Final fields that are set from the constructor.</p>
<p>Other static methods.</p>
<p>Static properties and constants.</p>
<p>Mutable properties, each in the order getter, private field, setter, without newlines separating them.</p>
<p>Read-only properties (other than hashCode).</p>
<p>Operators (other than ==).</p>
<p>Methods (other than toString and build).</p>
<p>The build method, for Widget and State classes.</p>
<p>operator ==, hashCode, toString, and diagnostics-related methods, in that order.</p>
<h2 id="Constructor-syntax"><a href="#Constructor-syntax" class="headerlink" title="Constructor syntax"></a>Constructor syntax</h2><p>构造函数定义,如果没有参数传递给super则不需要调用super<br>构造函数超过2个参数以后</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// one-line constructor example</span></span><br><span class="line"><span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Foo</span> <span class="keyword">extends</span> <span class="title">StatelessWidget</span> </span>{</span><br><span class="line">  Foo(<span class="keyword">this</span>.bar, { Key key, <span class="keyword">this</span>.child }) : <span class="keyword">super</span>(key: key);</span><br><span class="line">  <span class="keyword">final</span> <span class="built_in">int</span> bar;</span><br><span class="line">  <span class="keyword">final</span> Widget child;</span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// fully expanded constructor example</span></span><br><span class="line"><span class="keyword">abstract</span> <span class="class"><span class="keyword">class</span> <span class="title">Foo</span> <span class="keyword">extends</span> <span class="title">StatelessWidget</span> </span>{</span><br><span class="line">  Foo(</span><br><span class="line">    <span class="keyword">this</span>.bar, {</span><br><span class="line">    Key key,</span><br><span class="line">    Widget childWidget,</span><br><span class="line">  }) : child = childWidget,</span><br><span class="line">       <span class="keyword">super</span>(</span><br><span class="line">         key: key,</span><br><span class="line">       );</span><br><span class="line">  <span class="keyword">final</span> <span class="built_in">int</span> bar;</span><br><span class="line">  <span class="keyword">final</span> Widget child;</span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Prefer-a-maximum-line-length-of-80-characters"><a href="#Prefer-a-maximum-line-length-of-80-characters" class="headerlink" title="Prefer a maximum line length of 80 characters"></a>Prefer a maximum line length of 80 characters</h2><figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD (breaks after assignment operator and still goes over 80 chars)</span></span><br><span class="line"><span class="keyword">final</span> <span class="built_in">int</span> a = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">final</span> <span class="built_in">int</span> b = <span class="number">2</span>;</span><br><span class="line"><span class="keyword">final</span> <span class="built_in">int</span> c =</span><br><span class="line">    a.very.very.very.very.very.long.expression.that.returns.three.eventually().but.<span class="keyword">is</span>.very.long();</span><br><span class="line"><span class="keyword">final</span> <span class="built_in">int</span> d = <span class="number">4</span>;</span><br><span class="line"><span class="keyword">final</span> <span class="built_in">int</span> e = <span class="number">5</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// BETTER (consistent lines, not much longer than the earlier example)</span></span><br><span class="line"><span class="keyword">final</span> <span class="built_in">int</span> a = <span class="number">1</span>;</span><br><span class="line"><span class="keyword">final</span> <span class="built_in">int</span> b = <span class="number">2</span>;</span><br><span class="line"><span class="keyword">final</span> <span class="built_in">int</span> c = a.very.very.very.very.very.long.expression.that.returns.three.eventually().but.<span class="keyword">is</span>.very.long();</span><br><span class="line"><span class="keyword">final</span> <span class="built_in">int</span> d = <span class="number">4</span>;</span><br><span class="line"><span class="keyword">final</span> <span class="built_in">int</span> e = <span class="number">5</span>;</span><br></pre></td></tr></tbody></table></figure>

<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD (breaks after assignment operator)</span></span><br><span class="line"><span class="keyword">final</span> <span class="built_in">List</span>&lt;FooBarBaz&gt; _members =</span><br><span class="line">  &lt;FooBarBaz&gt;[<span class="keyword">const</span> Quux(), <span class="keyword">const</span> Qaax(), <span class="keyword">const</span> Qeex()];</span><br><span class="line"></span><br><span class="line"><span class="comment">// BETTER (only slightly goes over 80 chars)</span></span><br><span class="line"><span class="keyword">final</span> <span class="built_in">List</span>&lt;FooBarBaz&gt; _members = &lt;FooBarBaz&gt;[<span class="keyword">const</span> Quux(), <span class="keyword">const</span> Qaax(), <span class="keyword">const</span> Qeex()];</span><br><span class="line"></span><br><span class="line"><span class="comment">// BETTER STILL (fits in 80 chars)推荐这种写法,可以使用逗号分割,自动格式化换行</span></span><br><span class="line"><span class="keyword">final</span> <span class="built_in">List</span>&lt;FooBarBaz&gt; _members = &lt;FooBarBaz&gt;[</span><br><span class="line">  <span class="keyword">const</span> Quux(),</span><br><span class="line">  <span class="keyword">const</span> Qaax(),</span><br><span class="line">  <span class="keyword">const</span> Qeex(),</span><br><span class="line">];</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Indent-multi-line-argument-and-parameter-lists-by-2-characters"><a href="#Indent-multi-line-argument-and-parameter-lists-by-2-characters" class="headerlink" title="Indent multi-line argument and parameter lists by 2 characters"></a>Indent multi-line argument and parameter lists by 2 characters</h2><p>构造函数多行显示时,锁进2行</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">Foo f = Foo(</span><br><span class="line">  bar: <span class="number">1.0</span>,</span><br><span class="line">  quux: <span class="number">2.0</span>,</span><br><span class="line">);</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Use-a-trailing-comma-for-arguments-parameters-and-list-items-but-only-if-they-each-have-their-own-line"><a href="#Use-a-trailing-comma-for-arguments-parameters-and-list-items-but-only-if-they-each-have-their-own-line" class="headerlink" title="Use a trailing comma for arguments, parameters, and list items, but only if they each have their own line."></a>Use a trailing comma for arguments, parameters, and list items, but only if they each have their own line.</h2><p>使用逗号将多个参数分行, list,set,map,function </p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">List</span>&lt;<span class="built_in">int</span>&gt; myList = [</span><br><span class="line">  <span class="number">1</span>,</span><br><span class="line">  <span class="number">2</span>,</span><br><span class="line">];</span><br><span class="line">myList = &lt;<span class="built_in">int</span>&gt;[<span class="number">3</span>, <span class="number">4</span>];</span><br><span class="line"></span><br><span class="line">foo1(</span><br><span class="line">  bar,</span><br><span class="line">  baz,</span><br><span class="line">);</span><br><span class="line">foo2(bar, baz);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//BAD</span></span><br><span class="line"><span class="built_in">List</span>&lt;Quux&gt; myLongList2 = &lt;Quux&gt;[ Quux(<span class="number">1</span>), Quux(<span class="number">2</span>) ];</span><br><span class="line"></span><br><span class="line"><span class="comment">//GOOD</span></span><br><span class="line"><span class="built_in">List</span>&lt;Quux&gt; myLongList2 = &lt;Quux&gt;[</span><br><span class="line">  Quux(<span class="number">1</span>),</span><br><span class="line">  Quux(<span class="number">2</span>),</span><br><span class="line">];</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Prefer-single-quotes-for-strings"><a href="#Prefer-single-quotes-for-strings" class="headerlink" title="Prefer single quotes for strings"></a>Prefer single quotes for strings</h2><p>对于一般的字符串使用单引号, 对于嵌套字符串使用双引号</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="string">'Hello <span class="subst">${name.split(<span class="string">" "</span>)[<span class="number">0</span>]}</span>'</span>);</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Consider-using-⇒-for-short-functions-and-methods"><a href="#Consider-using-⇒-for-short-functions-and-methods" class="headerlink" title="Consider using ⇒ for short functions and methods"></a>Consider using ⇒ for short functions and methods</h2><p>使用更短的函数,一行表示</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD:</span></span><br><span class="line"><span class="built_in">String</span> capitalize(<span class="built_in">String</span> s) =&gt;</span><br><span class="line">  <span class="string">'<span class="subst">${s[<span class="number">0</span>].toUpperCase()}</span><span class="subst">${s.substring(<span class="number">1</span>)}</span>'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"><span class="built_in">String</span> capitalize(<span class="built_in">String</span> s) =&gt; <span class="string">'<span class="subst">${s[<span class="number">0</span>].toUpperCase()}</span><span class="subst">${s.substring(<span class="number">1</span>)}</span>'</span>;</span><br><span class="line"></span><br><span class="line"><span class="built_in">String</span> capitalize(<span class="built_in">String</span> s) {</span><br><span class="line">  <span class="keyword">return</span> <span class="string">'<span class="subst">${s[<span class="number">0</span>].toUpperCase()}</span><span class="subst">${s.substring(<span class="number">1</span>)}</span>'</span>;</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Use-⇒-for-inline-callbacks-that-just-return-list-or-map-literals"><a href="#Use-⇒-for-inline-callbacks-that-just-return-list-or-map-literals" class="headerlink" title="Use ⇒ for inline callbacks that just return list or map literals"></a>Use ⇒ for inline callbacks that just return list or map literals</h2><p>多使用<code>=&gt;</code>替换只有一行的闭包语句</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// GOOD, but slightly more verbose than necessary since it doesn't use =&gt;</span></span><br><span class="line"><span class="meta">@override</span></span><br><span class="line">Widget build(BuildContext context) {</span><br><span class="line">  <span class="keyword">return</span> PopupMenuButton&lt;<span class="built_in">String</span>&gt;(</span><br><span class="line">    onSelected: (<span class="built_in">String</span> value) { <span class="built_in">print</span>(<span class="string">'Selected: <span class="subst">$value</span>'</span>); },</span><br><span class="line">    itemBuilder: (BuildContext context) {</span><br><span class="line">      <span class="keyword">return</span> &lt;PopupMenuItem&lt;<span class="built_in">String</span>&gt;&gt;[</span><br><span class="line">        PopupMenuItem&lt;<span class="built_in">String</span>&gt;(</span><br><span class="line">          value: <span class="string">'Friends'</span>,</span><br><span class="line">          child: MenuItemWithIcon(Icons.people, <span class="string">'Friends'</span>, <span class="string">'5 new'</span>)</span><br><span class="line">        ),</span><br><span class="line">        PopupMenuItem&lt;<span class="built_in">String</span>&gt;(</span><br><span class="line">          value: <span class="string">'Events'</span>,</span><br><span class="line">          child: MenuItemWithIcon(Icons.event, <span class="string">'Events'</span>, <span class="string">'12 upcoming'</span>)</span><br><span class="line">        ),</span><br><span class="line">      ];</span><br><span class="line">    }</span><br><span class="line">  );</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD, does use =&gt;, slightly briefer</span></span><br><span class="line"><span class="meta">@override</span></span><br><span class="line">Widget build(BuildContext context) {</span><br><span class="line">  <span class="keyword">return</span> PopupMenuButton&lt;<span class="built_in">String</span>&gt;(</span><br><span class="line">    onSelected: (<span class="built_in">String</span> value) { <span class="built_in">print</span>(<span class="string">'Selected: <span class="subst">$value</span>'</span>); },</span><br><span class="line">    itemBuilder: (BuildContext context) =&gt; &lt;PopupMenuItem&lt;<span class="built_in">String</span>&gt;&gt;[</span><br><span class="line">      PopupMenuItem&lt;<span class="built_in">String</span>&gt;(</span><br><span class="line">        value: <span class="string">'Friends'</span>,</span><br><span class="line">        child: MenuItemWithIcon(Icons.people, <span class="string">'Friends'</span>, <span class="string">'5 new'</span>)</span><br><span class="line">      ),</span><br><span class="line">      PopupMenuItem&lt;<span class="built_in">String</span>&gt;(</span><br><span class="line">        value: <span class="string">'Events'</span>,</span><br><span class="line">        child: MenuItemWithIcon(Icons.event, <span class="string">'Events'</span>, <span class="string">'12 upcoming'</span>)</span><br><span class="line">      ),</span><br><span class="line">    ]</span><br><span class="line">  );</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Prefer-single-line-for-short-collection-if-and-collection-for"><a href="#Prefer-single-line-for-short-collection-if-and-collection-for" class="headerlink" title="Prefer single line for short collection-if and collection-for"></a>Prefer single line for short collection-if and collection-for</h2><p>对于简单的<code>if,else</code>或者<code>for</code>语句,使用一行表示</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD</span></span><br><span class="line"><span class="keyword">final</span> <span class="built_in">List</span>&lt;<span class="built_in">String</span>&gt; args = &lt;<span class="built_in">String</span>&gt;[</span><br><span class="line">  <span class="string">'test'</span>,</span><br><span class="line">  <span class="keyword">if</span> (useFlutterTestFormatter) <span class="string">'-rjson'</span></span><br><span class="line">  <span class="keyword">else</span> <span class="string">'-rcompact'</span>,</span><br><span class="line">  <span class="string">'-j1'</span>,</span><br><span class="line">  <span class="keyword">if</span> (!hasColor)</span><br><span class="line">    <span class="string">'--no-color'</span>,</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">final</span> <span class="built_in">String</span> opt <span class="keyword">in</span> others)</span><br><span class="line">    opt,</span><br><span class="line">];</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD</span></span><br><span class="line"><span class="keyword">final</span> <span class="built_in">List</span>&lt;<span class="built_in">String</span>&gt; args = &lt;<span class="built_in">String</span>&gt;[</span><br><span class="line">  <span class="string">'test'</span>,</span><br><span class="line">  <span class="keyword">if</span> (useFlutterTestFormatter) <span class="string">'-rjson'</span> <span class="keyword">else</span> <span class="string">'-rcompact'</span>,</span><br><span class="line">  <span class="string">'-j1'</span>,</span><br><span class="line">  <span class="keyword">if</span> (!hasColor) <span class="string">'--no-color'</span>,</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">final</span> <span class="built_in">String</span> opt <span class="keyword">in</span> others) opt,</span><br><span class="line">];</span><br></pre></td></tr></tbody></table></figure>

<p>或者多行显示,使用2个空格分割</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// GOOD</span></span><br><span class="line"><span class="keyword">final</span> <span class="built_in">List</span>&lt;<span class="built_in">String</span>&gt; args = &lt;<span class="built_in">String</span>&gt;[</span><br><span class="line">  <span class="string">'test'</span>,</span><br><span class="line">  <span class="keyword">if</span> (useFlutterTestFormatter)</span><br><span class="line">    <span class="string">'-rjson.very.very.very.very.very.very.very.very.long'</span></span><br><span class="line">  <span class="keyword">else</span></span><br><span class="line">    <span class="string">'-rcompact.very.very.very.very.very.very.very.very.long'</span>,</span><br><span class="line">  <span class="string">'-j1'</span>,</span><br><span class="line">  <span class="keyword">if</span> (!hasColor)</span><br><span class="line">    <span class="string">'--no-color.very.very.very.very.very.very.very.very.long'</span>,</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">final</span> <span class="built_in">String</span> opt <span class="keyword">in</span> others)</span><br><span class="line">    methodVeryVeryVeryVeryVeryVeryVeryVeryVeryLong(opt),</span><br><span class="line">];</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Put-spread-inside-collection-if-or-collection-for-on-the-same-line"><a href="#Put-spread-inside-collection-if-or-collection-for-on-the-same-line" class="headerlink" title="Put spread inside collection-if or collection-for on the same line"></a>Put spread inside collection-if or collection-for on the same line</h2><p>级连操作符<code>...</code>和<code>for,if</code>语句保持在同一行,增加代码的可读性</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD</span></span><br><span class="line"><span class="keyword">final</span> <span class="built_in">List</span>&lt;<span class="built_in">String</span>&gt; args = &lt;<span class="built_in">String</span>&gt;[</span><br><span class="line">  <span class="string">'test'</span>,</span><br><span class="line">  <span class="keyword">if</span> (condA) </span><br><span class="line">    ...&lt;<span class="built_in">String</span>&gt;[</span><br><span class="line">      <span class="string">'b'</span>,</span><br><span class="line">      <span class="string">'c'</span>,</span><br><span class="line">    ]</span><br><span class="line">  <span class="keyword">else</span></span><br><span class="line">    <span class="string">'-rcompact'</span>,</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">final</span> <span class="built_in">String</span> opt <span class="keyword">in</span> others)</span><br><span class="line">    ...&lt;<span class="built_in">String</span>&gt;[</span><br><span class="line">      m1(opt),</span><br><span class="line">      m2(opt),</span><br><span class="line">    ],</span><br><span class="line">];</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD</span></span><br><span class="line"><span class="keyword">final</span> <span class="built_in">List</span>&lt;<span class="built_in">String</span>&gt; args = &lt;<span class="built_in">String</span>&gt;[</span><br><span class="line">  <span class="string">'test'</span>,</span><br><span class="line">  <span class="keyword">if</span> (condA) ...&lt;<span class="built_in">String</span>&gt;[</span><br><span class="line">    <span class="string">'b'</span>,</span><br><span class="line">    <span class="string">'c'</span>,</span><br><span class="line">  ] <span class="keyword">else</span></span><br><span class="line">    <span class="string">'-rcompact'</span>,</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">final</span> <span class="built_in">String</span> opt <span class="keyword">in</span> others) ...&lt;<span class="built_in">String</span>&gt;[</span><br><span class="line">    m1(opt),</span><br><span class="line">    m2(opt),</span><br><span class="line">  ],</span><br><span class="line">];</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Separate-the-‘if’-expression-from-its-statement"><a href="#Separate-the-‘if’-expression-from-its-statement" class="headerlink" title="Separate the ‘if’ expression from its statement"></a>Separate the ‘if’ expression from its statement</h2><p>不要将<code>return</code>和<code>if</code>语句不要放在一行,这样会导致容易忽略潜在的代码</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD:</span></span><br><span class="line"><span class="keyword">if</span> (notReady) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"><span class="keyword">if</span> (notReady)</span><br><span class="line">  <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ALSO GOOD:</span></span><br><span class="line"><span class="keyword">if</span> (notReady) {</span><br><span class="line">  <span class="keyword">return</span>;</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<p>如果<code>if</code>和<code>else</code>有多行,则需要使用<code>{}</code></p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD:</span></span><br><span class="line"><span class="keyword">if</span> (foo)</span><br><span class="line">  bar(</span><br><span class="line">    <span class="string">'baz'</span>,</span><br><span class="line">  );</span><br><span class="line"></span><br><span class="line"><span class="comment">// BAD:</span></span><br><span class="line"><span class="keyword">if</span> (foo)</span><br><span class="line">  bar();</span><br><span class="line"><span class="keyword">else</span></span><br><span class="line">  baz();</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"><span class="keyword">if</span> (foo) {</span><br><span class="line">  bar(</span><br><span class="line">    <span class="string">'baz'</span>,</span><br><span class="line">  );</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"><span class="keyword">if</span> (foo) {</span><br><span class="line">  bar();</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line">  baz();</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<p>其它</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// VERY BAD:</span></span><br><span class="line"><span class="keyword">if</span> (foo)</span><br><span class="line">  bar();</span><br><span class="line">  baz();</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"><span class="keyword">if</span> (foo)</span><br><span class="line">  bar();</span><br><span class="line">baz();</span><br><span class="line"></span><br><span class="line"><span class="comment">// ALSO GOOD:</span></span><br><span class="line"><span class="keyword">if</span> (foo) {</span><br><span class="line">  bar();</span><br><span class="line">  baz();</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Align-expressions"><a href="#Align-expressions" class="headerlink" title="Align expressions"></a>Align expressions</h2><p>表达式变量位置对齐</p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// BAD:</span></span><br><span class="line"><span class="keyword">if</span> (foo.foo.foo + bar.bar.bar * baz - foo.foo.foo * <span class="number">2</span> +</span><br><span class="line">    bar.bar.bar * <span class="number">2</span> * baz &gt; foo.foo.foo) {</span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD (notice how it makes it obvious that this code can be simplified):</span></span><br><span class="line"><span class="keyword">if</span> (foo.foo.foo     + bar.bar.bar     * baz -</span><br><span class="line">    foo.foo.foo * <span class="number">2</span> + bar.bar.bar * <span class="number">2</span> * baz   &gt; foo.foo.foo) {</span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">}</span><br><span class="line"><span class="comment">// After simplification, it fits on one line anyway:</span></span><br><span class="line"><span class="keyword">if</span> (bar.bar.bar * <span class="number">3</span> * baz &gt; foo.foo.foo * <span class="number">2</span>) {</span><br><span class="line">  <span class="comment">// ...</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// BAD:</span></span><br><span class="line"><span class="keyword">return</span> foo.x == x &amp;&amp;</span><br><span class="line">    foo.y == y &amp;&amp;</span><br><span class="line">    foo.z == z;</span><br><span class="line"></span><br><span class="line"><span class="comment">// GOOD:</span></span><br><span class="line"><span class="keyword">return</span> foo.x == x &amp;&amp;</span><br><span class="line">       foo.y == y &amp;&amp;</span><br><span class="line">       foo.z == z;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ALSO GOOD:</span></span><br><span class="line"><span class="keyword">return</span> foo.x == x</span><br><span class="line">    &amp;&amp; foo.y == y</span><br><span class="line">    &amp;&amp; foo.z == z;</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Prefer-over"><a href="#Prefer-over" class="headerlink" title="Prefer += over ++"></a>Prefer += over ++</h2><h2 id="Use-double-literals-for-double-constants"><a href="#Use-double-literals-for-double-constants" class="headerlink" title="Use double literals for double constants"></a>Use double literals for double constants</h2><p>指定传入参数的类型如果<code>foo</code>使用一个<code>double</code>变量<code>foo(1.0)</code></p>
<figure class="highlight dart"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//BAD although it can convert to double</span></span><br><span class="line"><span class="keyword">void</span> main() {</span><br><span class="line">  foo(<span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">void</span> foo(<span class="built_in">double</span> value) {</span><br><span class="line">  <span class="built_in">print</span>(value);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//GOOD</span></span><br><span class="line"><span class="keyword">void</span> main() {</span><br><span class="line">  foo(<span class="number">1.0</span>);</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure>

<h2 id="Features-we-expect-every-widget-to-implement"><a href="#Features-we-expect-every-widget-to-implement" class="headerlink" title="Features we expect every widget to implement"></a>Features we expect every widget to implement</h2><p>Flutter framework现在已经基本成熟,新的widget建议增加这些特性</p>
<p>增加<code>accessibility</code>,辅助功能选项<br>增加<code>localisation</code><br>支持<code>Directionality</code>,可以任意的进行方向切换<br>文本缩放至少支持3.0x<br>为每个member对象添加文档<br>处理大量数据时不要block ui线程<br>处理好widget的生命周期事件，确保所有的订阅被及时的关闭.如binding observer,subscribions,timers,controllers<br>对每个独立的功能进行测试</p>
<h2 id="Use-of-streams-in-Flutter-framework-code"><a href="#Use-of-streams-in-Flutter-framework-code" class="headerlink" title="Use of streams in Flutter framework code"></a>Use of streams in Flutter framework code</h2><p><code>Stream</code>是一个比较重量级的<code>API</code>,推荐使用<code>Listenable</code>的子类(e.g <code>ValueNotifier</code>或者<code>ChangeNotifier</code>)</p>
<h2 id="Packages-Structure"><a href="#Packages-Structure" class="headerlink" title="Packages Structure"></a>Packages Structure</h2><p>每个库文件保留一个专门的文件用于导出所有对外暴露的接口<br>例如<code>rendering.dart</code>在<code>lib/src/rendering/*.dart</code>导出所有的公开文件</p>
<h2 id="Import-conventions"><a href="#Import-conventions" class="headerlink" title="Import conventions"></a>Import conventions</h2><p>使用<code>show</code>,<code>hide</code>,<code>as</code>关键字更好的约束库文件,减少dart文件的体积,减少命名冲突</p>
<p>例如<code>import 'dart:ui' show ...</code>, <code>dart:math as math</code></p>

                
            </div>
            <hr/>

            

    <div class="reprint" id="reprint-statement">
        
            <div class="reprint__author">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-user">
                        jiodg45:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="/jiodg45/about" rel="external nofollow noreferrer">Longxiang.guo</a>
                </span>
            </div>
            <div class="reprint__type">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-link">
                        文章链接:
                    </i>
                </span>
                <span class="reprint-info">
                    <a href="https://jiodg45.gitee.io/jiodg45/jiodg45/2021/03/11/flutter/code-review-process/">https://jiodg45.gitee.io/jiodg45/jiodg45/2021/03/11/flutter/code-review-process/</a>
                </span>
            </div>
            <div class="reprint__notice">
                <span class="reprint-meta" style="font-weight: bold;">
                    <i class="fas fa-copyright">
                        版权声明:
                    </i>
                </span>
                <span class="reprint-info">
                    本博客所有文章除特別声明外，均采用
                    <a href="https://creativecommons.org/licenses/by/4.0/deed.zh" rel="external nofollow noreferrer" target="_blank">CC BY 4.0</a>
                    许可协议。转载请注明来源
                    <a href="/jiodg45/about" target="_blank">Longxiang.guo</a>
                    !
                </span>
            </div>
        
    </div>

    <script async defer>
      document.addEventListener("copy", function (e) {
        let toastHTML = '<span>复制成功，请遵循本文的转载规则</span><button class="btn-flat toast-action" onclick="navToReprintStatement()" style="font-size: smaller">查看</a>';
        M.toast({html: toastHTML})
      });

      function navToReprintStatement() {
        $("html, body").animate({scrollTop: $("#reprint-statement").offset().top - 80}, 800);
      }
    </script>



            <div class="tag_share" style="display: block;">
                <div class="post-meta__tag-list" style="display: inline-block;">
                    
                        <div class="article-tag">
                            
                                <a href="/jiodg45/tags/flutter/">
                                    <span class="chip bg-color">flutter</span>
                                </a>
                            
                        </div>
                    
                </div>
                <div class="post_share" style="zoom: 80%; width: fit-content; display: inline-block; float: right; margin: -0.15rem 0;">
                    <link rel="stylesheet" type="text/css" href="/jiodg45/libs/share/css/share.min.css">
<div id="article-share">

    
    <div class="social-share" data-sites="twitter,facebook,google,qq,qzone,wechat,weibo,douban,linkedin" data-wechat-qrcode-helper="<p>微信扫一扫即可分享！</p>"></div>
    <script src="/jiodg45/libs/share/js/social-share.min.js"></script>
    

    

</div>

                </div>
            </div>
            
        </div>
    </div>

    

    

    

    

    

    

    

    

    

<article id="prenext-posts" class="prev-next articles">
    <div class="row article-row">
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge left-badge text-color">
                <i class="fas fa-chevron-left"></i>&nbsp;上一篇</div>
            <div class="card">
                <a href="/jiodg45/2021/03/11/flutter/flutter-resources/">
                    <div class="card-image">
                        
                        
                        <img src="/jiodg45/medias/featureimages/0.jpg" class="responsive-img" alt="FLutter精选文章">
                        
                        <span class="card-title">FLutter精选文章</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            Flutter&Dart编码规范
                        
                    </div>
                    <div class="publish-info">
                        <span class="publish-date">
                            <i class="far fa-clock fa-fw icon-date"></i>2021-03-11
                        </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/jiodg45/categories/flutter/" class="post-category">
                                    flutter
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/jiodg45/tags/flutter/">
                        <span class="chip bg-color">flutter</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
        
        <div class="article col s12 m6" data-aos="fade-up">
            <div class="article-badge right-badge text-color">
                下一篇&nbsp;<i class="fas fa-chevron-right"></i>
            </div>
            <div class="card">
                <a href="/jiodg45/2021/03/11/flutter/dart-vm/">
                    <div class="card-image">
                        
                        
                        <img src="/jiodg45/medias/featureimages/16.jpg" class="responsive-img" alt="Dart VM">
                        
                        <span class="card-title">Dart VM</span>
                    </div>
                </a>
                <div class="card-content article-content">
                    <div class="summary block-with-text">
                        
                            Dart VM介绍
                        
                    </div>
                    <div class="publish-info">
                            <span class="publish-date">
                                <i class="far fa-clock fa-fw icon-date"></i>2021-03-11
                            </span>
                        <span class="publish-author">
                            
                            <i class="fas fa-bookmark fa-fw icon-category"></i>
                            
                            <a href="/jiodg45/categories/flutter/" class="post-category">
                                    flutter
                                </a>
                            
                            
                        </span>
                    </div>
                </div>
                
                <div class="card-action article-tags">
                    
                    <a href="/jiodg45/tags/flutter/">
                        <span class="chip bg-color">flutter</span>
                    </a>
                    
                </div>
                
            </div>
        </div>
        
    </div>
</article>

</div>



<!-- 代码块功能依赖 -->
<script type="text/javascript" src="/jiodg45/libs/codeBlock/codeBlockFuction.js"></script>

<!-- 代码语言 -->

<script type="text/javascript" src="/jiodg45/libs/codeBlock/codeLang.js"></script>


<!-- 代码块复制 -->

<script type="text/javascript" src="/jiodg45/libs/codeBlock/codeCopy.js"></script>


<!-- 代码块收缩 -->

<script type="text/javascript" src="/jiodg45/libs/codeBlock/codeShrink.js"></script>


    </div>
    <div id="toc-aside" class="expanded col l3 hide-on-med-and-down">
        <div class="toc-widget card" style="background-color: white;">
            <div class="toc-title"><i class="far fa-list-alt"></i>&nbsp;&nbsp;目录</div>
            <div id="toc-content"></div>
        </div>
    </div>
</div>

<!-- TOC 悬浮按钮. -->

<div id="floating-toc-btn" class="hide-on-med-and-down">
    <a class="btn-floating btn-large bg-color">
        <i class="fas fa-list-ul"></i>
    </a>
</div>


<script src="/jiodg45/libs/tocbot/tocbot.min.js"></script>
<script>
    $(function () {
        tocbot.init({
            tocSelector: '#toc-content',
            contentSelector: '#articleContent',
            headingsOffset: -($(window).height() * 0.4 - 45),
            collapseDepth: Number('0'),
            headingSelector: 'h2, h3, h4'
        });

        // modify the toc link href to support Chinese.
        let i = 0;
        let tocHeading = 'toc-heading-';
        $('#toc-content a').each(function () {
            $(this).attr('href', '#' + tocHeading + (++i));
        });

        // modify the heading title id to support Chinese.
        i = 0;
        $('#articleContent').children('h2, h3, h4').each(function () {
            $(this).attr('id', tocHeading + (++i));
        });

        // Set scroll toc fixed.
        let tocHeight = parseInt($(window).height() * 0.4 - 64);
        let $tocWidget = $('.toc-widget');
        $(window).scroll(function () {
            let scroll = $(window).scrollTop();
            /* add post toc fixed. */
            if (scroll > tocHeight) {
                $tocWidget.addClass('toc-fixed');
            } else {
                $tocWidget.removeClass('toc-fixed');
            }
        });

        
        /* 修复文章卡片 div 的宽度. */
        let fixPostCardWidth = function (srcId, targetId) {
            let srcDiv = $('#' + srcId);
            if (srcDiv.length === 0) {
                return;
            }

            let w = srcDiv.width();
            if (w >= 450) {
                w = w + 21;
            } else if (w >= 350 && w < 450) {
                w = w + 18;
            } else if (w >= 300 && w < 350) {
                w = w + 16;
            } else {
                w = w + 14;
            }
            $('#' + targetId).width(w);
        };

        // 切换TOC目录展开收缩的相关操作.
        const expandedClass = 'expanded';
        let $tocAside = $('#toc-aside');
        let $mainContent = $('#main-content');
        $('#floating-toc-btn .btn-floating').click(function () {
            if ($tocAside.hasClass(expandedClass)) {
                $tocAside.removeClass(expandedClass).hide();
                $mainContent.removeClass('l9');
            } else {
                $tocAside.addClass(expandedClass).show();
                $mainContent.addClass('l9');
            }
            fixPostCardWidth('artDetail', 'prenext-posts');
        });
        
    });
</script>

    

</main>




    <footer class="page-footer bg-color">
    
        <link rel="stylesheet" href="/jiodg45/libs/aplayer/APlayer.min.css">
<style>
    .aplayer .aplayer-lrc p {
        
        display: none;
        
        font-size: 12px;
        font-weight: 700;
        line-height: 16px !important;
    }

    .aplayer .aplayer-lrc p.aplayer-lrc-current {
        
        display: none;
        
        font-size: 15px;
        color: #42b983;
    }

    
    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body {
        left: -66px !important;
    }

    .aplayer.aplayer-fixed.aplayer-narrow .aplayer-body:hover {
        left: 0px !important;
    }

    
</style>
<div class="">
    
    <div class="row">
        <meting-js class="col l8 offset-l2 m10 offset-m1 s12"
                   server="netease"
                   type="playlist"
                   id="503838841"
                   fixed='true'
                   autoplay='false'
                   theme='#42b983'
                   loop='all'
                   order='random'
                   preload='auto'
                   volume='0.7'
                   list-folded='true'
        >
        </meting-js>
    </div>
</div>

<script src="/jiodg45/libs/aplayer/APlayer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/meting@2/dist/Meting.min.js"></script>

    
    <div class="container row center-align" style="margin-bottom: 0px !important;">
        <div class="col s12 m8 l8 copy-right">
            Copyright&nbsp;&copy;
            
                <span id="year">2019-2021</span>
            
            <span id="year">2019</span>
            <a href="/jiodg45/about" target="_blank">Longxiang.Guo</a>
            |&nbsp;Powered by&nbsp;<a href="https://hexo.io/" target="_blank">Hexo</a>
            |&nbsp;Theme&nbsp;<a href="https://github.com/blinkfox/hexo-theme-matery" target="_blank">Matery</a>
            <br>
            
            
            
            
            
            
            <span id="busuanzi_container_site_pv">
                |&nbsp;<i class="far fa-eye"></i>&nbsp;总访问量:&nbsp;<span id="busuanzi_value_site_pv"
                    class="white-color"></span>&nbsp;次
            </span>
            
            
            <span id="busuanzi_container_site_uv">
                |&nbsp;<i class="fas fa-users"></i>&nbsp;总访问人数:&nbsp;<span id="busuanzi_value_site_uv"
                    class="white-color"></span>&nbsp;人
            </span>
            
            <br>
            
            <br>
            
        </div>
        <div class="col s12 m4 l4 social-link social-statis">
    <a href="https://github.com/LongXiangGuo" class="tooltipped" target="_blank" data-tooltip="访问我的GitHub" data-position="top" data-delay="50">
        <i class="fab fa-github"></i>
    </a>



    <a href="mailto:290657563@qq.com" class="tooltipped" target="_blank" data-tooltip="邮件联系我" data-position="top" data-delay="50">
        <i class="fas fa-envelope-open"></i>
    </a>







    <a href="tencent://AddContact/?fromId=50&fromSubId=1&subcmd=all&uin=290657563" class="tooltipped" target="_blank" data-tooltip="QQ联系我: 290657563" data-position="top" data-delay="50">
        <i class="fab fa-qq"></i>
    </a>







</div>
    </div>
</footer>

<div class="progress-bar"></div>


    <!-- 搜索遮罩框 -->
<div id="searchModal" class="modal">
    <div class="modal-content">
        <div class="search-header">
            <span class="title"><i class="fas fa-search"></i>&nbsp;&nbsp;搜索</span>
            <input type="search" id="searchInput" name="s" placeholder="请输入搜索的关键字"
                   class="search-input">
        </div>
        <div id="searchResult"></div>
    </div>
</div>

<script type="text/javascript">
$(function () {
    var searchFunc = function (path, search_id, content_id) {
        'use strict';
        $.ajax({
            url: path,
            dataType: "xml",
            success: function (xmlResponse) {
                // get the contents from search data
                var datas = $("entry", xmlResponse).map(function () {
                    return {
                        title: $("title", this).text(),
                        content: $("content", this).text(),
                        url: $("url", this).text()
                    };
                }).get();
                var $input = document.getElementById(search_id);
                var $resultContent = document.getElementById(content_id);
                $input.addEventListener('input', function () {
                    var str = '<ul class=\"search-result-list\">';
                    var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
                    $resultContent.innerHTML = "";
                    if (this.value.trim().length <= 0) {
                        return;
                    }
                    // perform local searching
                    datas.forEach(function (data) {
                        var isMatch = true;
                        var data_title = data.title.trim().toLowerCase();
                        var data_content = data.content.trim().replace(/<[^>]+>/g, "").toLowerCase();
                        var data_url = data.url;
                        data_url = data_url.indexOf('/') === 0 ? data.url : '/' + data_url;
                        var index_title = -1;
                        var index_content = -1;
                        var first_occur = -1;
                        // only match artiles with not empty titles and contents
                        if (data_title !== '' && data_content !== '') {
                            keywords.forEach(function (keyword, i) {
                                index_title = data_title.indexOf(keyword);
                                index_content = data_content.indexOf(keyword);
                                if (index_title < 0 && index_content < 0) {
                                    isMatch = false;
                                } else {
                                    if (index_content < 0) {
                                        index_content = 0;
                                    }
                                    if (i === 0) {
                                        first_occur = index_content;
                                    }
                                }
                            });
                        }
                        // show search results
                        if (isMatch) {
                            str += "<li><a href='" + data_url + "' class='search-result-title'>" + data_title + "</a>";
                            var content = data.content.trim().replace(/<[^>]+>/g, "");
                            if (first_occur >= 0) {
                                // cut out 100 characters
                                var start = first_occur - 20;
                                var end = first_occur + 80;
                                if (start < 0) {
                                    start = 0;
                                }
                                if (start === 0) {
                                    end = 100;
                                }
                                if (end > content.length) {
                                    end = content.length;
                                }
                                var match_content = content.substr(start, end);
                                // highlight all keywords
                                keywords.forEach(function (keyword) {
                                    var regS = new RegExp(keyword, "gi");
                                    match_content = match_content.replace(regS, "<em class=\"search-keyword\">" + keyword + "</em>");
                                });

                                str += "<p class=\"search-result\">" + match_content + "...</p>"
                            }
                            str += "</li>";
                        }
                    });
                    str += "</ul>";
                    $resultContent.innerHTML = str;
                });
            }
        });
    };

    searchFunc('/jiodg45/search.xml', 'searchInput', 'searchResult');
});
</script>

    <!-- 回到顶部按钮 -->
<div id="backTop" class="top-scroll">
    <a class="btn-floating btn-large waves-effect waves-light" href="#!">
        <i class="fas fa-arrow-up"></i>
    </a>
</div>


    <script src="/jiodg45/libs/materialize/materialize.min.js"></script>
    <script src="/jiodg45/libs/masonry/masonry.pkgd.min.js"></script>
    <script src="/jiodg45/libs/aos/aos.js"></script>
    <script src="/jiodg45/libs/scrollprogress/scrollProgress.min.js"></script>
    <script src="/jiodg45/libs/lightGallery/js/lightgallery-all.min.js"></script>
    <script src="/jiodg45/js/matery.js"></script>

    <!-- Baidu Analytics -->

    <!-- Baidu Push -->

<script>
    (function () {
        var bp = document.createElement('script');
        var curProtocol = window.location.protocol.split(':')[0];
        if (curProtocol === 'https') {
            bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
        } else {
            bp.src = 'http://push.zhanzhang.baidu.com/push.js';
        }
        var s = document.getElementsByTagName("script")[0];
        s.parentNode.insertBefore(bp, s);
    })();
</script>

    
    <script src="/jiodg45/libs/others/clicklove.js" async="async"></script>
    
    
    <script async src="/jiodg45/libs/others/busuanzi.pure.mini.js"></script>
    

    

    

    <!--腾讯兔小巢-->
    
    

    

    

    
    <script src="/jiodg45/libs/instantpage/instantpage.js" type="module"></script>
    

</body>

</html>
